package com.novunda.platform.entities;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.google.common.collect.Lists;
import com.novunda.platform.common.utils.Collections3;
import com.novunda.platform.entities.base.DataEntity;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Where;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import java.util.Date;
import java.util.List;

/**
 * 用户Entity
 *
 * @author slacrey
 * @version 2014-6-17
 */
@Entity
@Table(name = "sys_user")
@DynamicInsert
@DynamicUpdate
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User extends DataEntity {

    private static final long serialVersionUID = 1L;
    private Long id;        // 编号
    private int state;		// 状态0正常， 1 激活，2冻结
    private Office company;    // 归属公司
    private Office office;    // 归属部门
    private String loginName;// 登录名
    private String password;// 密码
    private String no;        // 工号
    private String realName;    // 姓名
    private String email;    // 邮箱
    private String phone;    // 电话
    private String mobile;    // 手机
    private String avatar;    // 用户头像地址
    private String userType;// 用户类型
    private String loginIp;    // 最后登陆IP
    private Date loginDate;    // 最后登陆日期

    private List<Long> roleIdList = Lists.newArrayList();

    private Integer bindStatus = 0;//绑定状态   0未绑定


    //发送邮件专用
    private String uuid;
    //邮件发送时间
    private Long emailSendTime;

    private List<Role> roleList = Lists.newArrayList(); // 拥有角色列表

    private int index;

    @Transient
    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public User() {
    }

    public User(Long id) {
        this();
        this.id = id;
    }

    public User(Long id, String loginName, String password, String name) {
        this.id = id;
        this.loginName = loginName;
        this.password = password;
        this.realName = name;
    }

    @Column(name = "bindStatus")
    public Integer getBindStatus() {
        return bindStatus;
    }

    public void setBindStatus(Integer bindStatus) {
        this.bindStatus = bindStatus;
    }




    @Column(name = "uuid")
    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    @Column(name = "email_send_time")
    public Long getEmailSendTime() {
        return emailSendTime;
    }

    public void setEmailSendTime(Long emailSendTime) {
        this.emailSendTime = emailSendTime;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "state")
    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    @ManyToOne
    @JoinColumn(name = "company_id", nullable = true)
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnore
//	@NotNull(message="归属公司不能为空")
    public Office getCompany() {
        return company;
    }

    public void setCompany(Office company) {
        this.company = company;
    }

    @ManyToOne
    @JoinColumn(name = "office_id", nullable = true)
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnore
//	@NotNull(message="归属部门不能为空")
    public Office getOffice() {
        return office;
    }

    public void setOffice(Office office) {
        this.office = office;
    }

    @Column(name = "login_name")
    @Length(min = 1, max = 100)
    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    @JsonIgnore
    @Length(min = 1, max = 100)
    @Column(name = "password")
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Length(min = 1, max = 100)
    @Column(name = "name")
    public String getRealName() {
        return realName;
    }


    @Length(min = 0, max = 50)
    @Column(name = "no")
    public String getNo() {
        return no;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public void setNo(String no) {
        this.no = no;
    }

    @Email
    @Length(min = 0, max = 200)
    @Column(name = "email")
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Length(min = 0, max = 200)
    @Column(name = "phone")
    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Length(min = 0, max = 200)
    @Column(name = "mobile")
    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    @Length(min = 0, max = 255)
    @Column(name = "avatar")
    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    @Length(min = 0, max = 100)
    @Column(name = "user_type")
    public String getUserType() {
        return userType;
    }

    public void setUserType(String userType) {
        this.userType = userType;
    }

    @Column(name = "login_ip")
    public String getLoginIp() {
        return loginIp;
    }

    public void setLoginIp(String loginIp) {
        this.loginIp = loginIp;
    }

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "login_date")
    public Date getLoginDate() {
        return loginDate;
    }

    @SuppressWarnings("AssignmentToDateFieldFromParameter")
    public void setLoginDate(Date loginDate) {
        this.loginDate = loginDate;
    }

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "sys_user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    @Where(clause = "del_flag='" + User.DEL_FLAG_NORMAL + "'")
    @OrderBy("id")
    @Fetch(FetchMode.SUBSELECT)
    @NotFound(action = NotFoundAction.IGNORE)
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @JsonIgnore
    public List<Role> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<Role> roleList) {
        this.roleList = roleList;
    }

    @Transient
    @JsonIgnore
    public List<Long> getRoleIdList() {
//      List<Long> roleIdList = Lists.newArrayList();
//        for (Role role : roleList) {
//            roleIdList.add(role.getId());
//        }
        return roleIdList;
    }

    @Transient
    public void setRoleIdList(List<Long> roleIdList) {
        roleList = Lists.newArrayList();
        for (Long roleId : roleIdList) {
            Role role = new Role();
            role.setId(roleId);
            roleList.add(role);
        }
        this.roleIdList = roleIdList;
    }

    /**
     * 用户拥有的角色名称字符串, 多个角色名称用','分隔.
     */
    @Transient
    public String getRoleNames() {
        return Collections3.extractToString(roleList, "name", ", ");
    }

    @Transient
    public boolean isAdmin() {
        return isAdmin(id);
    }

    @Transient
    public static boolean isAdmin(Long id) {
        return Long.valueOf(1L).equals(id);
    }

}
